package com.guxingke.typecho4j.widget.dispatcher;

import com.guxingke.typecho4j.Typecho4j;
import com.guxingke.typecho4j.Typecho4jException;
import com.guxingke.typecho4j.route.DispatcherStrategy;
import com.guxingke.typecho4j.route.Route;
import com.guxingke.typecho4j.route.Routes;
import com.guxingke.typecho4j.util.ControllerUtil;
import com.guxingke.typecho4j.widget.Widget;
import com.guxingke.typecho4j.widget.WidgetDispatcher;
import com.guxingke.typecho4j.widget.WidgetFactory;
import com.guxingke.typecho4j.widget.WidgetHandle;
import com.guxingke.typecho4j.widget.WidgetRoute;
import com.guxingke.typecho4j.widget.layout.LayoutWidget;
import com.jfinal.core.Controller;

/**
 * 默认分发组件，作为所有分发组件的父类
 * 
 * @author guxingke
 */
public class DefaultDispatcherWidget extends Widget implements WidgetDispatcher {
	protected Routes routes;

	@Override
	public boolean init() {
		initLogger();
		routes = Typecho4j.typecho4j().getRoutes();
		return true;
	}

	@Override
	public void dispatcher(Controller controller) throws Typecho4jException {
		logger.warn("archiveWidget excute ::: DispatcherKey:"
				+ ControllerUtil.getDispatcherKey(controller));

		handle(controller, ControllerUtil.getDispatcherKey(controller));
	}

	/**
	 * 处理请求<br/>
	 * 1.获取key对应的路由<br/>
	 * 2.根据路由信息，调用对应的处理组件进行处理<br/>
	 * 3.根据路由信息，分发至某view<br/>
	 * 
	 * @param controller
	 * @param key
	 * @throws Typecho4jException
	 */
	protected void handle(Controller controller, String key)
			throws Typecho4jException {
		Route route = routes.getRoute(key);

		if (route == null) {
			throw new Typecho4jException(404, "route not found");
		}

		doHandle(route.getRouteClass(), controller);

		// 如果路由中viewPath为null,则说明render会被处理组件调用
		if (route.getViewPath() == null) {
			return;
		} else if (route.getDispatcherStrategy() == DispatcherStrategy.FORWARD) {
			controller.render(route.getViewPath());
		} else {
			controller.redirect(route.getViewPath());
		}
	}

	/**
	 * 
	 * 根据得到的组件class，从widgetFactory中获取对应的Route实例，处理请求
	 * 
	 * @param routeClass
	 * @param controller
	 * @throws Typecho4jException
	 */
	protected void doHandle(Class<? extends WidgetRoute> routeClass,
			Controller controller) throws Typecho4jException {

		WidgetRoute route = WidgetFactory.route(routeClass);

		try {
			LayoutWidget layout = (LayoutWidget) route;
			layout.excute(controller);
		} catch (ClassCastException exception) {
			WidgetHandle handle = (WidgetHandle) route;
			handle.handle(controller);
		}
	}
}
